package handler

import (
	"net/http"
	"time"

	"less_day/internal/model"
	"less_day/internal/utils"

	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"gorm.io/gorm"
)

type UserHandler struct {
	db  *gorm.DB
	rdb *redis.Client
}

func NewUserHandler(db *gorm.DB, rdb *redis.Client) *UserHandler {
	return &UserHandler{db: db, rdb: rdb}
}

func (h *UserHandler) WechatLogin(c *gin.Context) {
	var req model.WechatLoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, model.APIResponse{
			Code:    400,
			Message: "请求参数错误",
			Data:    nil,
		})
		return
	}

	// 获取微信OpenID
	openID, err := utils.GetWechatOpenID(req.Code)
	if err != nil {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "微信登录失败",
			Data:    nil,
		})
		return
	}

	// 查找或创建用户
	var user model.User
	if err := h.db.Where("openid = ?", openID).First(&user).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			// 创建新用户
			user = model.User{
				OpenID:    openID,
				CreatedAt: time.Now(),
				UpdatedAt: time.Now(),
			}
			if err := h.db.Create(&user).Error; err != nil {
				c.JSON(http.StatusInternalServerError, model.APIResponse{
					Code:    500,
					Message: "创建用户失败",
					Data:    nil,
				})
				return
			}
		} else {
			c.JSON(http.StatusInternalServerError, model.APIResponse{
				Code:    500,
				Message: "数据库错误",
				Data:    nil,
			})
			return
		}
	}

	// 生成JWT token
	token, err := utils.GenerateToken(user.ID, user.OpenID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, model.APIResponse{
			Code:    500,
			Message: "生成token失败",
			Data:    nil,
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "登录成功",
		Data: gin.H{
			"token": token,
			"user": gin.H{
				"id":             user.ID,
				"openid":         user.OpenID,
				"nickname":       user.Nickname,
				"avatar_url":     user.AvatarURL,
				"total_days":     user.TotalDays,
				"total_items":    user.TotalItems,
				"current_streak": user.CurrentStreak,
				"longest_streak": user.LongestStreak,
				"created_at":     user.CreatedAt,
			},
		},
	})
}

func (h *UserHandler) PhoneLogin(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "用户未登录",
			Data:    nil,
		})
		return
	}

	var req model.PhoneLoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, model.APIResponse{
			Code:    400,
			Message: "请求参数错误",
			Data:    nil,
		})
		return
	}

	// 获取手机号
	phone, err := utils.GetWechatPhoneNumber("", req.PhoneCode)
	if err != nil {
		c.JSON(http.StatusBadRequest, model.APIResponse{
			Code:    400,
			Message: "获取手机号失败",
			Data:    nil,
		})
		return
	}

	// 更新用户手机号
	if err := h.db.Model(&model.User{}).Where("id = ?", userID).Update("phone", phone).Error; err != nil {
		c.JSON(http.StatusInternalServerError, model.APIResponse{
			Code:    500,
			Message: "更新手机号失败",
			Data:    nil,
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "绑定手机号成功",
		Data:    gin.H{"phone": phone},
	})
}

func (h *UserHandler) GetProfile(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "用户未登录",
			Data:    nil,
		})
		return
	}

	var user model.User
	if err := h.db.First(&user, userID).Error; err != nil {
		c.JSON(http.StatusNotFound, model.APIResponse{
			Code:    404,
			Message: "用户不存在",
			Data:    nil,
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "获取用户信息成功",
		Data: gin.H{
			"id":             user.ID,
			"openid":         user.OpenID,
			"phone":          user.Phone,
			"nickname":       user.Nickname,
			"avatar_url":     user.AvatarURL,
			"total_days":     user.TotalDays,
			"total_items":    user.TotalItems,
			"current_streak": user.CurrentStreak,
			"longest_streak": user.LongestStreak,
			"created_at":     user.CreatedAt,
		},
	})
}

func (h *UserHandler) UpdateProfile(c *gin.Context) {
	userID, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, model.APIResponse{
			Code:    401,
			Message: "用户未登录",
			Data:    nil,
		})
		return
	}

	var updateData struct {
		Nickname  string `json:"nickname"`
		AvatarURL string `json:"avatar_url"`
	}

	if err := c.ShouldBindJSON(&updateData); err != nil {
		c.JSON(http.StatusBadRequest, model.APIResponse{
			Code:    400,
			Message: "请求参数错误",
			Data:    nil,
		})
		return
	}

	updates := map[string]interface{}{}
	if updateData.Nickname != "" {
		updates["nickname"] = updateData.Nickname
	}
	if updateData.AvatarURL != "" {
		updates["avatar_url"] = updateData.AvatarURL
	}

	if err := h.db.Model(&model.User{}).Where("id = ?", userID).Updates(updates).Error; err != nil {
		c.JSON(http.StatusInternalServerError, model.APIResponse{
			Code:    500,
			Message: "更新用户信息失败",
			Data:    nil,
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Code:    200,
		Message: "更新用户信息成功",
		Data:    nil,
	})
}
